package com.ford.microservices.services.web;

import com.ford.microservices.common.AccountDto;
import com.ford.microservices.common.SignUpResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.Valid;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Logger;

/**
 * Client controller, fetches Account info from the microservice via
 * {@link WebAccountsService}.
 */
@Controller
public class WebAccountsController {

    @Autowired
    protected WebAccountsService accountsService;
    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private AuthenticationManager authenticationManager;

    protected Logger logger = Logger.getLogger(WebAccountsController.class
            .getName());

    public WebAccountsController(WebAccountsService accountsService) {
        this.accountsService = accountsService;
    }

    @PostMapping("/signIn")
    @ResponseBody
    public AccountDto signIn(@RequestBody @Valid SignInDto signInDto) throws Exception {
        try {
            authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(signInDto.getUsername(), signInDto.getPassword())
            );
        } catch (Exception ex) {
            throw new Exception("inavalid username/password");
        }
        String token = jwtUtil.generateToken(signInDto.getUsername());
        AccountDto accountDto = accountsService.findByCellPhone(signInDto.getUsername());
        accountDto.setToken(token);
        accountDto.setPassword(null);
        return accountDto;
    }

    @PostMapping("/signUp")
    @ResponseBody
    public AccountDto signUp(@RequestBody @Valid AccountDto signUpDto) throws Exception {
        SignUpResponse signUpResponse = accountsService.singUp(signUpDto);
        AccountDto accountDto = signUpResponse.getAccountDto();
        if(accountDto == null){
            throw new Exception(signUpResponse.getError());
        }
        String token = jwtUtil.generateToken(signUpDto.getCellPhone());
        accountDto.setToken(token);
        return signUpResponse.getAccountDto();
    }

    @RequestMapping("/checkin/{id}")
    @ResponseBody
    public ResponseEntity<String> checkin(@PathVariable("id") Long id) {
        logger.info("web-service checkin() invoked: " + id);
        ResponseEntity<String> result = accountsService.checkIn(id);
        logger.info("web-service checkin() found: " + result);
        return result;
    }

    @RequestMapping("/report")
    @ResponseBody
    public List<AccountDto> report() {
        logger.info("web-service report() invoked");
        return Arrays.asList(accountsService.report().getBody());
    }
}
